from flask import Blueprint, request
from flask_jwt_extended import jwt_required, get_jwt_identity
from app import db
from app.models import Article, ArticleCategory
from app.utils.response import success_response, error_response, paginated_response
from app.utils.decorators import admin_required
from app.models.operation_log import OperationLog
from loguru import logger

articles_bp = Blueprint('articles', __name__)

@articles_bp.route('/categories', methods=['GET'])
def get_categories():
    """获取文章分类列表"""
    try:
        categories = ArticleCategory.query.filter_by(is_active=True).order_by(ArticleCategory.sort_order).all()
        return success_response([category.to_dict() for category in categories])
    except Exception as e:
        logger.error(f"获取文章分类失败: {e}")
        return error_response('获取分类失败', 500)

@articles_bp.route('/', methods=['GET'])
def get_articles():
    """获取文章列表"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 10, type=int), 100)
        category_id = request.args.get('category_id', type=int)
        
        query = Article.query.filter_by(is_published=True)
        
        if category_id:
            query = query.filter_by(category_id=category_id)
        
        pagination = query.order_by(Article.created_at.desc()).paginate(
            page=page,
            per_page=per_page,
            error_out=False
        )
        
        articles = []
        for article in pagination.items:
            article_dict = article.to_dict()
            # 添加分类信息
            article_dict['category'] = article.category.to_dict()
            articles.append(article_dict)
        
        return paginated_response(
            articles,
            page,
            per_page,
            pagination.total
        )
        
    except Exception as e:
        logger.error(f"获取文章列表失败: {e}")
        return error_response('获取文章列表失败', 500)

@articles_bp.route('/<int:article_id>', methods=['GET'])
def get_article(article_id):
    """获取文章详情"""
    try:
        article = Article.query.filter_by(id=article_id, is_published=True).first()
        
        if not article:
            return error_response('文章不存在', 404)
        
        # 增加浏览次数
        article.increment_view_count()
        
        article_dict = article.to_dict()
        article_dict['category'] = article.category.to_dict()
        
        return success_response(article_dict)
        
    except Exception as e:
        logger.error(f"获取文章详情失败: {e}")
        return error_response('获取文章详情失败', 500)

@articles_bp.route('/<int:article_id>/view', methods=['POST'])
def view_article(article_id):
    """增加文章浏览量"""
    try:
        article = Article.query.filter_by(id=article_id, is_published=True).first()
        
        if not article:
            return error_response('文章不存在', 404)
        
        article.increment_view_count()
        
        return success_response({'message': '浏览量已增加'})
        
    except Exception as e:
        logger.error(f"增加文章浏览量失败: {e}")
        return error_response('操作失败', 500)

@articles_bp.route('/<int:article_id>/like', methods=['POST'])
@jwt_required()
def like_article(article_id):
    """文章点赞"""
    try:
        current_user_id = get_jwt_identity()
        
        article = Article.query.filter_by(id=article_id, is_published=True).first()
        if not article:
            return error_response('文章不存在', 404)
        
        # 检查是否已经点赞过
        from app.models.user import UserArticleLike
        existing_like = UserArticleLike.query.filter_by(
            user_id=current_user_id,
            article_id=article_id
        ).first()
        
        if existing_like:
            return error_response('已经点赞过了', 400)
        
        # 创建点赞记录
        like = UserArticleLike(
            user_id=current_user_id,
            article_id=article_id
        )
        db.session.add(like)
        
        # 增加文章点赞数
        article.like_count = (article.like_count or 0) + 1
        db.session.commit()
        
        return success_response({'message': '点赞成功'})
        
    except Exception as e:
        logger.error(f"文章点赞失败: {e}")
        return error_response('点赞失败', 500)

@articles_bp.route('/<int:article_id>/collect', methods=['POST'])
@jwt_required()
def collect_article(article_id):
    """文章收藏"""
    try:
        current_user_id = get_jwt_identity()
        
        article = Article.query.filter_by(id=article_id, is_published=True).first()
        if not article:
            return error_response('文章不存在', 404)
        
        # 检查是否已经收藏过
        from app.models.user import UserArticleCollection
        existing_collection = UserArticleCollection.query.filter_by(
            user_id=current_user_id,
            article_id=article_id
        ).first()
        
        if existing_collection:
            return error_response('已经收藏过了', 400)
        
        # 创建收藏记录
        collection = UserArticleCollection(
            user_id=current_user_id,
            article_id=article_id
        )
        db.session.add(collection)
        
        # 增加文章收藏数
        article.collect_count = (article.collect_count or 0) + 1
        db.session.commit()
        
        return success_response({'message': '收藏成功'})
        
    except Exception as e:
        logger.error(f"文章收藏失败: {e}")
        return error_response('收藏失败', 500)

# 管理员接口
@articles_bp.route('/admin/categories', methods=['GET'])
@admin_required
def admin_get_categories():
    """管理员获取文章分类列表"""
    try:
        categories = ArticleCategory.query.order_by(ArticleCategory.sort_order).all()
        return success_response([category.to_dict() for category in categories])
    except Exception as e:
        logger.error(f"管理员获取文章分类失败: {e}")
        return error_response('获取分类失败', 500)

@articles_bp.route('/admin/categories', methods=['POST'])
@admin_required
def create_category():
    """创建文章分类"""
    try:
        data = request.get_json()
        name = data.get('name')
        description = data.get('description', '')
        sort_order = data.get('sort_order', 0)
        
        if not name:
            return error_response('分类名称不能为空', 400)
        
        # 检查分类名是否已存在
        existing = ArticleCategory.query.filter_by(name=name).first()
        if existing:
            return error_response('分类名称已存在', 400)
        
        category = ArticleCategory(
            name=name,
            description=description,
            sort_order=sort_order
        )
        
        db.session.add(category)
        db.session.commit()
        
        # 记录操作日志
        current_admin_id = get_jwt_identity().split('_')[1]
        OperationLog.log_operation(
            action='create_article_category',
            description=f'创建文章分类: {name}',
            admin_id=current_admin_id,
            resource_type='article_category',
            resource_id=category.id
        )
        
        return success_response(category.to_dict(), '分类创建成功')
        
    except Exception as e:
        logger.error(f"创建文章分类失败: {e}")
        return error_response('创建分类失败', 500)

@articles_bp.route('/admin/categories/<int:category_id>', methods=['PUT'])
@admin_required
def update_category(category_id):
    """更新文章分类"""
    try:
        category = ArticleCategory.query.get(category_id)
        if not category:
            return error_response('分类不存在', 404)
        
        data = request.get_json()
        name = data.get('name')
        description = data.get('description')
        sort_order = data.get('sort_order')
        is_active = data.get('is_active')
        
        if name is not None:
            # 检查分类名是否已存在（排除自己）
            existing = ArticleCategory.query.filter(
                ArticleCategory.name == name,
                ArticleCategory.id != category_id
            ).first()
            if existing:
                return error_response('分类名称已存在', 400)
            category.name = name
        
        if description is not None:
            category.description = description
        if sort_order is not None:
            category.sort_order = sort_order
        if is_active is not None:
            category.is_active = is_active
        
        db.session.commit()
        
        # 记录操作日志
        current_admin_id = get_jwt_identity().split('_')[1]
        OperationLog.log_operation(
            action='update_article_category',
            description=f'更新文章分类: {category.name}',
            admin_id=current_admin_id,
            resource_type='article_category',
            resource_id=category.id
        )
        
        return success_response(category.to_dict(), '分类更新成功')
        
    except Exception as e:
        logger.error(f"更新文章分类失败: {e}")
        return error_response('更新分类失败', 500)

@articles_bp.route('/admin/', methods=['GET'])
@admin_required
def admin_get_articles():
    """管理员获取文章列表"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 10, type=int), 100)
        category_id = request.args.get('category_id', type=int)
        is_published = request.args.get('is_published', type=lambda v: v.lower() == 'true')
        
        query = Article.query
        
        if category_id:
            query = query.filter_by(category_id=category_id)
        if is_published is not None:
            query = query.filter_by(is_published=is_published)
        
        pagination = query.order_by(Article.created_at.desc()).paginate(
            page=page,
            per_page=per_page,
            error_out=False
        )
        
        articles = []
        for article in pagination.items:
            article_dict = article.to_dict()
            article_dict['category'] = article.category.to_dict()
            articles.append(article_dict)
        
        return paginated_response(
            articles,
            page,
            per_page,
            pagination.total
        )
        
    except Exception as e:
        logger.error(f"管理员获取文章列表失败: {e}")
        return error_response('获取文章列表失败', 500)

@articles_bp.route('/admin/', methods=['POST'])
@admin_required
def create_article():
    """创建文章"""
    try:
        data = request.get_json()
        category_id = data.get('category_id')
        title = data.get('title')
        content = data.get('content')
        summary = data.get('summary', '')
        cover_image = data.get('cover_image', '')
        is_published = data.get('is_published', False)
        
        if not all([category_id, title, content]):
            return error_response('分类ID、标题和内容不能为空', 400)
        
        # 检查分类是否存在
        category = ArticleCategory.query.get(category_id)
        if not category:
            return error_response('分类不存在', 400)
        
        current_admin_id = int(get_jwt_identity().split('_')[1])
        
        article = Article(
            category_id=category_id,
            title=title,
            content=content,
            summary=summary,
            cover_image=cover_image,
            is_published=is_published,
            created_by=current_admin_id
        )
        
        if is_published:
            from datetime import datetime
            article.published_at = datetime.utcnow()
        
        db.session.add(article)
        db.session.commit()
        
        # 记录操作日志
        OperationLog.log_operation(
            action='create_article',
            description=f'创建文章: {title}',
            admin_id=current_admin_id,
            resource_type='article',
            resource_id=article.id
        )
        
        return success_response(article.to_dict(), '文章创建成功')
        
    except Exception as e:
        logger.error(f"创建文章失败: {e}")
        return error_response('创建文章失败', 500)

@articles_bp.route('/admin/<int:article_id>', methods=['PUT'])
@admin_required
def update_article(article_id):
    """更新文章"""
    try:
        article = Article.query.get(article_id)
        if not article:
            return error_response('文章不存在', 404)
        
        data = request.get_json()
        category_id = data.get('category_id')
        title = data.get('title')
        content = data.get('content')
        summary = data.get('summary')
        cover_image = data.get('cover_image')
        is_published = data.get('is_published')
        
        if category_id is not None:
            # 检查分类是否存在
            category = ArticleCategory.query.get(category_id)
            if not category:
                return error_response('分类不存在', 400)
            article.category_id = category_id
        
        if title is not None:
            article.title = title
        if content is not None:
            article.content = content
        if summary is not None:
            article.summary = summary
        if cover_image is not None:
            article.cover_image = cover_image
        if is_published is not None:
            article.is_published = is_published
            if is_published and not article.published_at:
                from datetime import datetime
                article.published_at = datetime.utcnow()
        
        db.session.commit()
        
        # 记录操作日志
        current_admin_id = int(get_jwt_identity().split('_')[1])
        OperationLog.log_operation(
            action='update_article',
            description=f'更新文章: {article.title}',
            admin_id=current_admin_id,
            resource_type='article',
            resource_id=article.id
        )
        
        return success_response(article.to_dict(), '文章更新成功')
        
    except Exception as e:
        logger.error(f"更新文章失败: {e}")
        return error_response('更新文章失败', 500)

@articles_bp.route('/admin/<int:article_id>', methods=['DELETE'])
@admin_required
def delete_article(article_id):
    """删除文章"""
    try:
        article = Article.query.get(article_id)
        if not article:
            return error_response('文章不存在', 404)
        
        title = article.title
        db.session.delete(article)
        db.session.commit()
        
        # 记录操作日志
        current_admin_id = int(get_jwt_identity().split('_')[1])
        OperationLog.log_operation(
            action='delete_article',
            description=f'删除文章: {title}',
            admin_id=current_admin_id,
            resource_type='article',
            resource_id=article_id
        )
        
        return success_response(None, '文章删除成功')
        
    except Exception as e:
        logger.error(f"删除文章失败: {e}")
        return error_response('删除文章失败', 500) 